package com.qdlc.p2p.biz.service.impl;

import java.util.Calendar;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.qdlc.p2p.biz.executer.AbstractExecuter;
import com.qdlc.p2p.biz.executer.ExecuterHelper;
import com.qdlc.p2p.biz.executer.impl.CashFailExecuter;
import com.qdlc.p2p.biz.executer.impl.CashNotifySuccessExecuter;
import com.qdlc.p2p.biz.executer.impl.CashSuccessExecuter;
import com.qdlc.p2p.biz.service.AccountCashService;
import com.qdlc.p2p.biz.tpp.TppBaseInterface;
import com.qdlc.p2p.biz.tpp.TppServiceFactory;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.dal.common.model.jpa.PageDataList;
import com.qdlc.p2p.dal.common.model.jpa.QueryParam;
import com.qdlc.p2p.dal.common.model.jpa.SearchFilter;
import com.qdlc.p2p.dal.dao.AccountCashDao;
import com.qdlc.p2p.dal.dao.AccountRechargeDao;
import com.qdlc.p2p.dal.dao.BorrowTenderDao;
import com.qdlc.p2p.dal.dao.OperationLogDao;
import com.qdlc.p2p.dal.dao.VerifyLogDao;
import com.qdlc.p2p.dal.dto.AccountCash;
import com.qdlc.p2p.dal.dto.AccountRecharge;
import com.qdlc.p2p.dal.dto.OperationLog;
import com.qdlc.p2p.dal.dto.Operator;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.VerifyLog;
import com.qdlc.p2p.dal.model.AccountCashModel;
import com.qdlc.p2p.dal.model.TppModel;
import com.qdlc.p2p.dal.util.UserUtils;

@Service("accountCashService")
public class AccountCashServiceImpl implements AccountCashService {
    @Resource
    private AccountRechargeDao accountRechargeDao;

    @Resource
    private AccountCashDao accountCashDao;

    @Resource
    private OperationLogDao operationLogDao;

    @Resource
    private VerifyLogDao verifyLogDao;

    @Resource
    private BorrowTenderDao borrowTenderDao;

    @Override
    public void save(AccountCash cash) {
        accountCashDao.insert(cash);
    }

    @Override
    public void doCancleCash(AccountCash cash, Operator operator) {
        User cashUesr = UserUtils.getUserById(cash.getUserId());
        accountCashDao.updateStatus(cash.getId(), 2, 0);
        OperationLog log = new OperationLog(cashUesr, operator, "cash_fail");
        log.setOperationResult("用户名为" + operator.getUserName() + "("
                + Global.getIP() + ")的操作员对用户为" + cashUesr.getUserName()
                + "的提现ID为" + cash.getId() + ")进行取消提现操作");
        operationLogDao.save(log);
    }

    @Override
    public void verifyCash(AccountCash cash, Operator operator) {
        accountCashDao.updateStatus(cash.getId(), 1, 0);
        Global.setTransfer("cash", cash);
        User cashUser = UserUtils.getUserById(cash.getUserId());
        AbstractExecuter executer = ExecuterHelper.getExecuter(CashNotifySuccessExecuter.class);
        executer.execute(cash.getMoney(), cashUser, operator, null);
    }

    @Override
    public PageDataList<AccountCashModel> list(long userId, int startPage, AccountCashModel model) {
        return accountCashDao.list(userId, startPage, model);
    }

    @Override
    public AccountCash getCashMessage(long userId) {
        return accountCashDao.getCashMessage(userId);
    }

    @Override
    public PageDataList<AccountCashModel> accountCashList(AccountCashModel model) {
        return accountCashDao.accountCashList(model);
    }

    @Override
    public int count(int status) {
        return accountCashDao.count(status);
    }

    @Override
    public AccountCash find(long id) {
        return accountCashDao.findById(id);
    }

    @Override
    public void kfVerifyCash(AccountCash cash, int status, Operator operator) {
        VerifyLog verifyLog = new VerifyLog(operator, "accountCash",
                cash.getId(), 1, cash.getStatus() == 5 ? 1 : -1, "");
        Global.setTransfer("cash", cash);
        Global.setTransfer("cashFee", cash.getFee());
        AccountCashModel model = AccountCashModel.instance(cash);
        Global.setTransfer("feeBearTip", model.getFeeBearTip());
        String flag = "";
        if (status == 1) {
            flag = "S";
        } else if (status == 2) {
            flag = "R";
        }
        //汇付取现审核
        User cashUser = UserUtils.getUserById(cash.getUserId());
        TppModel tppModel = new TppModel();
        TppBaseInterface tppService = TppServiceFactory.newIntance();
        tppModel.setOrderId(cash.getOrderNo());
        String tppUserCustId = cashUser.getTppUserCustId();
        tppModel.setTppUserCustId(tppUserCustId);
        tppModel.setMoney(cash.getAmount());
        tppModel.setUser(cashUser);
        tppModel.setFlag(flag);
        tppService.tppVerifyCash(tppModel);

        if (status == 1) { // 审核通过
            AbstractExecuter executer = ExecuterHelper.getExecuter(CashSuccessExecuter.class);
            executer.execute(cash.getMoney(), cashUser, operator);
            verifyLog.setRemark(operator.getRemark() + "(" + operator.getUserName() + "操作员提现审核通过【ID：" + cash.getId() + "】)");
        } else if (status == 2) {// 审核不通过
            AbstractExecuter executer = ExecuterHelper.getExecuter(CashFailExecuter.class);
            executer.execute(cash.getMoney(), cashUser, operator);
            verifyLog.setRemark(operator.getRemark() + "(" + operator.getUserName() + "操作员提现审核 不通过【ID：)" + cash.getId() + "】)");
        }
        accountCashDao.verifyCash(cash.getId(), status, cash.getStatus(), operator.getRemark(), operator.getUserName());
        verifyLogDao.save(verifyLog);
    }

    @Override
    public void cwVerifyCash(AccountCash cash, Operator operator) {
        VerifyLog verifyLog = new VerifyLog(operator, "verifyAccountCash", cash.getId(), 1, cash.getStatus(), "");
        Global.setTransfer("cash", cash);
        AccountCashModel model = AccountCashModel.instance(cash);
        Global.setTransfer("feeBearTip", model.getFeeBearTip());
        User cashUser = UserUtils.getUserById(cash.getUserId());
        if (cash.getStatus() == 1) { // 审核通过
            // checkCash(cash);
            AbstractExecuter executer = ExecuterHelper.getExecuter(CashSuccessExecuter.class);
            executer.execute(cash.getMoney(), cashUser, operator);
            verifyLog.setRemark(operator.getRemark() + "(" + operator.getUserName() + "操作员提现审核通过【ID：" + cash.getId() + "】)");
        } else {
            AbstractExecuter executer = ExecuterHelper.getExecuter(CashFailExecuter.class);
            executer.execute(cash.getMoney(), cashUser, operator);
            verifyLog.setRemark(operator.getRemark() + "(" + operator.getUserName() + "操作员提现审核失败【ID：" + cash.getId() + "】)");
        }
        verifyLogDao.save(verifyLog);
    }

    @Override
    public void updateWithdrawStatus(int interval,int status) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(DateUtil.getNow().getTime() - interval);
        List<AccountCash> list = accountCashDao.findByLimitAddTime(4, cal.getTime());
        for (AccountCash ac : list) {
            accountCashDao.updateStatus(ac.getId(), status, 4);
        }
    }

    @Override
    public double allCashMoney() {
        return accountCashDao.allCashMoney();
    }

    @Override
    public int getApplyingCount(long userId) {
        return accountCashDao.getApplyingCount(userId);
    }

    @Override
    public int getSingleDaytime(long userId) {
        return accountCashDao.getSingleDaytime(userId);
    }

    @Override
    public double getSingleDayAmount(long userId) {
        return accountCashDao.getSingleDayAmount(userId);
    }

    @Override
    public int getMonthFreeFeeTime(long userId) {
        return accountCashDao.getMonthFreeFeeTime(userId);
    }

    @Override
    public double getWithdrawCashManageFeeByUserId(long userId) {
        return accountCashDao.getWithdrawCashManageFeeByUserId(userId);
    }

    @Override
    public void updateRechargeStatus(int interval, int status) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(DateUtil.getNow().getTime() - interval);
        QueryParam queryParam = QueryParam.getInstance();
        queryParam.addParam("status", 0);
        queryParam.addParam("addTime", SearchFilter.Operators.LTE, cal.getTime());
        List<AccountRecharge> list = accountRechargeDao.findByCriteria(queryParam);
        for (AccountRecharge ac : list) {
            accountRechargeDao.updateStatus(ac.getId(), status);
        }
    }

    @Override
    public double getWithdrawAmountByDate(String date) {
        return accountCashDao.getWithdrawAmountByDate(date);
    }
}
